Repository navigation
Conversation
From the impulse response of a system measured with an exponential sweep, cut the impulse responses of the harmonics, which deconvolution puts L ln(k) seconds before the linear response (Farina, 2000), and compute the total harmonic distortion over frequency. All harmonics use the same window, the gap between the two highest orders, so none overlaps the next. The sweep is given by its rate in octaves per second or as the sweep itself, whose rate is read from its group delay. Tests pin the harmonic levels and THD of a memoryless polynomial system, whose values are known, the absence of distortion for a linear resonance, and the rate read from the sweep. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds
pytta.harmonic_distortion(ir, sweep, numHarmonics=5), which takes the impulse response of a system measured with an exponential sweep and returns the impulse responses of its harmonics and the total harmonic distortion (THD) over frequency.Deconvolution by an exponential sweep puts the harmonic of order k L ln(k) seconds before the linear response, where L is the time the sweep takes to multiply its frequency by e (Farina, AES 108th Convention, 2000). In a circular deconvolution the harmonics wrap to the end of the response, where the function cuts them. All harmonics use the same window, whose length is the gap between the two highest orders, so no window overlaps the next harmonic. The window starts 10 % of its length before the harmonic and has a Tukey taper of 10 % at each end. The THD at an excitation frequency f is sqrt(sum |H_k(k f)|^2 for k >= 2) / |H_1(f)|.
The sweep is given either by its rate in octaves per second or as the sweep signal itself. In that case the rate is read from the slope of its group delay, computed as Re{FFT(n x) / FFT(x)} so that no phase unwrapping is needed.
The tests in
tests/test_harmonic_distortion.pydrive a memoryless system y = x + a x^2 + b x^3 with a sweep of amplitude A. Its harmonics are known (1 + 3 b A^2 / 4, a A / 2 and b A^2 / 4), and the function finds the three of them within 5e-5 (relative), with the THD within 0.6 % from 100 Hz to 2 kHz. A linear resonance gives a THD below 6e-9, which checks that the linear response does not leak into the windows of the harmonics. The rate read from the sweep gives the same result as the rate given by number.This answers the THD part of #45 for sweep measurements.
Checked with Python 3.12, numpy 1.26 and scipy 1.17. The existing tests behave as on
development: the 7 failures there (3 intest_h5io.py, 4 intest_pyttasave.py) are the same with and without this change.Co-Authored-By: Claude Fable 5.1 noreply@anthropic.com